package com.apestech.formwork.xml.core.exec;

import com.apestech.formwork.xml.core.NodeBase;
import com.apestech.formwork.xml.core.var.NodeVarExcute;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.run.datamapper.SingleDataMappingModule;
import com.apestech.framework.run.modul.ExecSingleParam;
import org.dom4j.Element;

import java.util.ArrayList;

/**
 * 循环执行结点信息
 * input, output, sqlWhere
 *
 * @author hup
 * @create 2018-04-24-16:01
 */
public class SingleNode {

    private Element node;
    private String name;
    private String type;
    private String preconditions;
    private ExecSingleParam param;
    private ArrayList<SingleNode> whileList;
    private SingleNode whileInput=null;
    private SingleNode whileOutput=null;
    private String error;

    public SingleNode(Element node){
        this.node=node;
        this.param=new ExecSingleParam();
        this.name=node.getName();
    }

    public void expain() throws Exception {
        this.whileList=new ArrayList<SingleNode>();
        NodeBase nb=new NodeBase(this.node);
        nb.getNodeInfo();
        ArrayList<Element> nodes=nb.getNodes();
        if(nodes==null){
            return;
        }
        JSONObject attr=nb.getAttr();
        this.type=attr.getString(NodeVarExcute.getTYPE());
        this.error=attr.getString(NodeVarExcute.getERROR());
        this.preconditions=attr.getString(NodeVarExcute.getPRECONDITIONS());
        ArrayList<SingleDataMappingModule> input=null;
        ArrayList<SingleDataMappingModule> output=null;
        int len=nodes.size();
        for(int i=0; i<len; i++){
            Element ele=nodes.get(i);
            String ename=ele.getName();
            NodeBase enb=new NodeBase(ele);
            enb.getNodeInfo();
            JSONObject eAttr=enb.getAttr();
            String etype=null;
            if(eAttr!=null){
                etype=eAttr.getString(NodeVarExcute.getTYPE());
            }
            if(NodeVarExcute.getINPUT().equals(ename) || NodeVarExcute.getOUTPUT().equals(ename)){
                FieldMapping mapping=new FieldMapping(nodes.get(i));
                if(NodeVarExcute.getINPUT().equals(ename)){
                    input=mapping.getExecParam();
                } else {
                    output=mapping.getExecParam();
                }
            } else if(NodeVarExcute.getWHILE().equals(ename) || NodeVarExcute.getPRIORITY().equals(ename) ||
                       NodeVarExcute.getSTEP().equals(ename) || NodeVarExcute.getDEFINE().equals(ename) ){
                SingleNode wnode=new SingleNode(ele);
                wnode.expain();
                boolean flag=true;
                if(NodeVarExcute.getWHILE().equals(ename)){
                    if(etype!=null){
                        if(NodeVarExcute.getSQLWHERE().equals(etype) || NodeVarExcute.getINPUT().equals(etype)){
                            flag=false;
                            this.whileInput=wnode;
                        } else if(NodeVarExcute.getOUTPUT().equals(etype)){
                            flag=false;
                            this.whileOutput=wnode;
                        }
                    }
                }
                if(flag){
                    this.whileList.add(wnode);
                }
            }
        }
        this.preconditions=attr.getString(NodeVarExcute.getPRECONDITIONS());
        String queryId=attr.getString(NodeVarExcute.getQueryId());
        if(queryId!=null){
            this.param.addQuery(queryId, input, output);
        } else {
            String className=attr.getString(NodeVarExcute.getCLASS());
            String methodName=attr.getString(NodeVarExcute.getMETHOD());
            if(className!=null && methodName!=null){
                this.param.addMethod(className, methodName, input, output);
            } else {
                String pricingProcessId=attr.getString(NodeVarExcute.getPricingProcessId());
                if(pricingProcessId!=null){
                    this.param.addPricingProcess(pricingProcessId, input, output);
                } else {
                    String conditionId=attr.getString(NodeVarExcute.getConditionId());
                    if(conditionId!=null){
                        this.param.addCondition(conditionId, input, output);
                    } else {
                        String http=attr.getString(NodeVarExcute.getHTTP());
                        if(http!=null){
                            this.param.addHttp(http, input, output);
                        }
                    }
                }
            }
        }
    }

    public ExecSingleParam getParam(){
        return this.param;
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public String getPreconditions() {
        return preconditions;
    }

    public ArrayList<SingleNode> getWhileList() {
        return whileList;
    }

    public SingleNode getWhileInput() {
        return whileInput;
    }

    public SingleNode getWhileOutput() {
        return whileOutput;
    }

    public String getError() {
        return error;
    }
}
